/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package dnbW.dbW;

/**
 * Encapsulates an XPath step. Work as an nodes in the doubly-linked list.
 * @author zhouyong
 */
public class Step {

    public static final int AXIS_CHILD = 0;
    public static final int AXIS_DESCENDANT = 1;
    public static final int AXIS_PARENT = 2;
    public static final int AXIS_ANCESTOR = 3;
    public static final int AXIS_ATTRIBUTE = 4;
    
    public static final String[] AXIS_NAMES = {
      "child",
      "descendant",
      "parent",
      "ancestor",
      "attribute"
    };
    
    public static final String[] AXIS_ABBREVIATION = {
        "/",
        "//",
        "parent",
        "ancestor",
        "@"
    };

    // <editor-fold defaultstate="collapsed" desc="Axis">
    private int axis;

    public int getAxis() {
        return axis;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="QName">
    private String qName;

    public String getQName() {
        return qName;
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Prev">
    /**
     * Gets previous step
     */
    private Step prev;

    public Step getPrev() {
        return prev;
    }

    public void setPrev(Step prev) {
        this.prev = prev;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Next">
    private Step next;

    public Step getNext() {
        return next;
    }

    public void setNext(Step next) {
        this.next = next;
    }
    // </editor-fold>

    public Step(int axis, String qName, Step prev, Step next) {
        this.axis = axis;
        this.qName = qName;
        this.prev = prev;
        this.next = next;
    }
    
    public Step(String qname){
        this(AXIS_CHILD, qname, null, null);
    }
    
    public Step(int axis, String qName){
        this(axis, qName, null, null);
    }
    
    private boolean isAxisSupported(int axis){
        if(axis == AXIS_CHILD || axis == AXIS_ATTRIBUTE)
            return true;
        
        return false;
    }

    /**
     * Gets root step
     * @return
     */
    public Step getRoot(){
        Step root = this;
        while(root.getPrev() != null)
            root = root.getPrev();
        return root;
    }
    
    public boolean isAttribute(){
        return getAxis() == AXIS_ATTRIBUTE;
    }
    
    public boolean isLeaf(){
        return getNext() == null;
    }
    
    public boolean isLeafElement(){
        return getNext() == null && !isAttribute();
    }
    
    public String getText(){
        return "/" + AXIS_NAMES[getAxis()] + "::" + getQName();
    }
    
    public String getTextAbbreviation(){
        switch(getAxis()){
            case AXIS_CHILD:
                return "/" + getQName();
            case AXIS_DESCENDANT:
                return "//" + getQName();
            case AXIS_ATTRIBUTE:
                return "//@" + getQName();
            default:
                return getText();
        }
    }
}
